Vect = Vect or Class("Vect")

---@diagnostic disable-next-line: duplicate-set-field
function Vect:ctor(...)
	local tbl = {...}
	if type(tbl[1]) == 'table' then
		tbl = tbl[1]
	end
	self.length = #tbl
    for i = 1, self.length do
        self[i] = tbl[i]
    end
	self.length = #tbl
end
-- 重载+运算符
function Vect:__add(t)
    local tbl = {}
	if type(t) == 'number' then
		for i = 1, self.length do
			tbl[i] = self[i] + t
		end
	elseif type(t) == 'table' then
		local length = self.length
		local length2 = IsClassOf(t, 'Vect') and t.length or #t
		for i = 1, math.max(length, length2) do
			tbl[i] = (self[i] or 0) + (t[i] or 0)
		end
    end
    return self.class.new(tbl)
end

-- 重载-运算符
function Vect:__sub(t)
	local tbl = {}
	if type(t) == 'number' then
		for i = 1, self.length do
			tbl[i] = self[i] - t
		end
	elseif type(t) == 'table' then
		local length = self.length
		local length2 = IsClassOf(t, 'Vect') and t.length or #t
		for i = 1, math.max(length, length2) do
			tbl[i] = (self[i] or 0) - (t[i] or 0)
		end
	end
	return self.class.new(tbl)
end

-- 重载*运算符
function Vect:__mul(t)
	local tbl = {}
	if type(t) == 'number' then
		for i = 1, self.length do
			tbl[i] = self[i] * t
		end
	elseif type(t) == 'table' then
		for i = 1, math.min(IsClassOf(t, "Vect") and t.length or #t, self.length) do
			tbl[i] = self[i] * t[i]
		end
	end
	return self.class.new(tbl)
end

-- 重载/运算符
function Vect:__div(t)
	local tbl = {}
	if type(t) == 'number' then
		for i = 1, self.length do
			tbl[i] = tbl[i] / t
		end
	elseif type(t) == 'table' then
		for i = 1, math.min(IsClassOf(t, "Vect") and t.length or #t, self.length) do
			tbl[i] = self[i] / t[i]
		end
	end
	return self.class.new(tbl)
end

function Vect:unpack()
	return unpack(self)
end

function Vect:mag()
	local tmp = 0
	for i, v in ipairs(self) do
		tmp = tmp + v * v
	end
	return tmp
end

function Vect:magSqr()
	return math.sqrt(self:mag())
end

function Vect:clone()
	-- 不能用Vect.new 否则子类实例调用clone出来的是vect对象
	return self.class.new(self._props)
end

function Vect:normalize()
	local tbl = self:clone()
	local d = self:magSqr()
	if d ~= 0 then
		for i, v in ipairs(self) do
			tbl[i] = v / d
		end
	else
		return nil
	end
	return tbl
end

function Vect:__tostring()
	local str = 'Vect:'
	for i = 1, self.length do
		str = str..' '..self[i]
	end
	return str
end

function Vect.equals(v1, v2)
	for i, v in ipairs(v1) do
		if v2[i] ~= v then
			return false
		end
	end
	return true
end

function Vect:set(x, y)
	self.x = x
	self.y = y
end

Vect.defineProp('x', {
	get = function(self)
		return self[1]
	end,
	set = function(self, key, val)
		self[1] = val
	end
})

Vect.defineProp('y', {
	get = function(self)
		return self[2]
	end,
	set = function(self, key, val)
		self[2] = val
	end
})

function xy(x, y)
    return Vect.new({x, y})
end